package org.orbis.spikezolt;

import java.util.ArrayList;
import java.util.Iterator;

import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObject;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObjectGroup;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.util.Debug;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class MapLoader {
	private SpikeZoltActivity sa;
	public TMXTiledMap currentMap;

	public MapLoader(SpikeZoltActivity sa) {
		this.sa = sa;
	}

	public void load(String file) {
		// TMXLoader Initialization
		try {
			if (sa.tmxLoader == null) {
				sa.tmxLoader = new TMXLoader(sa,
						sa.mEngine.getTextureManager(),
						TextureOptions.BILINEAR_PREMULTIPLYALPHA,
						new ITMXTilePropertiesListener() {
							@Override
							public void onTMXTileWithPropertiesCreated(
									final TMXTiledMap pTMXTiledMap,
									final TMXLayer pTMXLayer,
									final TMXTile pTMXTile,
									final TMXProperties<TMXTileProperty> pTMXTileProperties) {

							}
						});
			}

			//MAP LOADING BEGINS HERE
			unload(currentMap); //Unload a map if one was all ready loaded
			currentMap = sa.tmxLoader.loadFromAsset(sa, "tmx/" + file + ".tmx");

			// OBJECTS
			ArrayList<TMXObjectGroup> objs = currentMap.getTMXObjectGroups();
			for (int i = 0; i < objs.size(); i++) {
				String objGroupName = objs.get(i).getName();

				if (objGroupName.equals("blocks")) {
					int numOfObjects = objs.get(i).getTMXObjects().size();
					for (int k = 0; k < numOfObjects; k++) {
						TMXObject tmxObject = objs.get(i).getTMXObjects()
								.get(k);
						int x = tmxObject.getX();
						int y = tmxObject.getY();
						int width = tmxObject.getWidth();
						int height = tmxObject.getHeight();
						String tmxName = tmxObject.getName();
						int xx = x, yy = y;
						if ((width % 16 == 0) && (height % 16 == 0)) {
							xx = width / 16;
							yy = height / 16;

							for (int w = 0; w < xx; w++) {
								for (int h = 0; h < yy; h++) {
									Block b = new Block(sa, x + (w * 16), y
											+ (h * 16), 16, 16, tmxName);
									sa.blocks.add(b);
								}
							}
						}
					}
				}

				else if (objGroupName.equals("walls")) {
					int numOfObjects = objs.get(i).getTMXObjects().size();
					for (int k = 0; k < numOfObjects; k++) {
						TMXObject wall = objs.get(i).getTMXObjects().get(k);
						final Shape boxShape = new Rectangle(wall.getX(),
								wall.getY(), wall.getWidth(), wall.getHeight());
						final FixtureDef wallFixtureDef = PhysicsFactory
								.createFixtureDef(0, 0.5f, 0.5f);
						// wallFixtureDef.isSensor = true;
						wallFixtureDef.restitution = 0.0f;
						wallFixtureDef.friction = sa.WALL_FRICTION;
						Body body = PhysicsFactory.createBoxBody(
								sa.mPhysicsWorld, boxShape,
								BodyType.StaticBody, wallFixtureDef);
						body.setUserData("wall");
					}
				}

				else if (objGroupName.equals("other")) {
					int numOfObjects = objs.get(i).getTMXObjects().size();
					for (int k = 0; k < numOfObjects; k++) {
						TMXObject tmxObject = objs.get(i).getTMXObjects()
								.get(k);
						int x = tmxObject.getX();
						int y = tmxObject.getY();
						String tmxName = tmxObject.getName();
						String tmxType = tmxObject.getType();
						TMXProperties objProps = tmxObject
								.getTMXObjectProperties();
						if (tmxType != null) {
							if (tmxType.equals("switch")) {
								Switch s = new Switch(sa, x, y, tmxName);
								sa.steps.add(s);
							}
						}
						if (tmxName.equals("tutorial")) {
							Tutorial tut = new Tutorial(sa, x, y, objProps.get(
									0).toString());
							sa.steps.add(tut);
						} else if (tmxName.equals("startPoint")) {
							if (sa.mPhysicsWorld != null) {
								sa.pl = new Player(sa, sa.scene, sa.mEngine,
										sa.mPhysicsWorld, x, y);
								sa.steps.add(sa.pl);
							}
						} else if (tmxName.equals("endPipe")) {
							if (sa.mPhysicsWorld != null) {
								EndPipe endPipe = new EndPipe(sa, x, y);
								sa.steps.add(endPipe);
							}
						}

					}
				}
			}

			final TMXLayer tmxLayer = currentMap.getTMXLayers().get(0);
			sa.scene.attachChild(tmxLayer);
			/*			
			for(TMXLayer l : currentMap.getTMXLayers()){			
			sa.scene.attachChild(l);
			}
			 */

			/* Make the camera not exceed the bounds of the TMXEntity. */
			sa.mCamera.setBounds(0, tmxLayer.getWidth(), 0,
					tmxLayer.getHeight());
			sa.mCamera.setBoundsEnabled(true);

		} catch (final TMXLoadException tmxle) {
			Debug.e(tmxle);
		}
	}

	public void unload(TMXTiledMap map) {
		if (map != null) {
			// Get rid of all blocks
			Iterator<Block> it = sa.blocks.iterator();
			while (it.hasNext()) {
				Block b = it.next();
				b.destroy(false);
				it.remove();
			}
			// Get rid of all updaters
			Iterator<Updater> up = sa.steps.iterator();
			while (up.hasNext()) {
				up.next().destroy();
				up.remove();
			}
			
			for(TMXLayer l : currentMap.getTMXLayers()){			
			l.detachSelf();	
			}
			
		}
	}

}
